Recode Data
Arab3
arab3 %<>%
mutate(cntry = sjmisc::to_label(country)) %>%
mutate(region = sjmisc::to_label(a1)) %>%
mutate(governorate = sjmisc::to_label(q1)) %>%
mutate(year = lubridate::year(date))
# Dependent Variable
arab3 %<>%
mutate(islamistparties1 = ifelse(q518a2 > 5, NA, 5 - q518a2)) %>%
mutate(islamistparties2 = ifelse(q518b2 > 5, NA, 5 - q518b2)) %>%
mutate(islamistparties = case_when(
islamistparties1 == 1 ~ 1,
islamistparties1 == 2 ~ 2,
islamistparties1 == 3 ~ 3,
islamistparties1 == 4 ~ 4,
islamistparties2 == 1 ~ 1,
islamistparties2 == 2 ~ 2,
islamistparties2 == 3 ~ 3,
islamistparties2 == 4 ~ 4)
) %>%
mutate(islamistgov = ifelse(q5184 > 5, NA, 5 - q5184)) %>%
mutate(religinterfere = ifelse(q6061 > 5, NA, q6061)) %>%
mutate(religleaders = ifelse(q6062 > 5, NA, 5 - q6062)) %>%
mutate(religleadersinfl = ifelse(q6063 > 5, NA, 5 - q6063)) %>%
mutate(seperation = ifelse(q6064 > 5, NA, q6064)) %>%
mutate(religparty = Recode(q605a, "1 = 1;
2 = 1;
3 = 0;
4 = 0;
5 = 0;
8 = 0;
9 = NA")) %>%
mutate(religparty2 = Recode(q605a, "1 = 5;
2 = 4;
3 = 2;
4 = 1;
5 = 3;
8 = NA;
9 = NA"))
ifelse4cat_rec <- function(variable) {
recoded <- ifelse(variable == 0 | variable > 5, NA, 5 - variable)
return(recoded)
}
arab3 %<>%
mutate(female = ifelse(sex == 2, 1, 0)) %>%
mutate(work = ifelse(q1004 == 0 | q1004 > 5, NA, abs(q1004 - 2))) %>%
mutate(income = ifelse4cat_rec(q1016)) %>%
mutate(age = ifelse(q1001 == 0 | q1001 == 9999, NA, q1001)) %>%
mutate(educ = case_when(
q1003 == 0 ~ NA_real_,
q1003 == 99 ~ NA_real_,
q1003 == 5 ~ 4,
q1003 == 6 ~ 5,
q1003 == 7 ~ 6,
q1003yem == 0 ~ NA_real_,
q1003yem == 99 ~ NA_real_,
q1003yem == 4 ~ 3,
q1003yem == 5 ~ 4,
q1003yem == 6 ~ 5,
q1003yem == 7 ~ 5,
q1003yem == 8 ~ 6,
q1003t == 0 ~ NA_real_,
q1003t == 99 ~ NA_real_,
q1003t == 1 ~ 1,
q1003t == 2 ~ 2,
q1003t == 3 ~ 3,
q1003t == 4 ~ 4,
q1003t == 5 ~ 5,
q1003t == 6 ~ 6,
TRUE ~ as.numeric(q1003))
) %>%
mutate(globalism = ifelse(q701b == 0 | q701b > 5, NA, q701b)) %>%
mutate(pray = ifelse(q6101 == 0 | q6101 > 5, NA, 6 - q6101)) %>%
mutate(quran = ifelse(q6106 == 0 | q6106 > 5, NA, 6 - q6106)) %>%
mutate(womanwork = ifelse(q6012 == 0 | q6012 > 5, NA, q6012)) %>%
mutate(womenleader = ifelse4cat_rec(q6013)) %>%
mutate(womeneduc = ifelse4cat_rec(q6014)) %>%
mutate(nodemoc = ifelse(q6071 == 0 | q6071 > 5, NA, q6071)) %>%
mutate(genderapartuni = ifelse4cat_rec(q6074)) %>%
mutate(coverup = ifelse4cat_rec(q6076)) %>%
select(cntry, year, region, governorate, islamistparties , islamistgov, religinterfere, religleaders, religleadersinfl, seperation, religparty, religparty2, female, work, income, age, educ, globalism, pray, quran, womanwork, womenleader, womeneduc, nodemoc, genderapartuni, coverup)
Arab4
table(arab4$country)
1 5 8 10 13 15 21
1199 1146 1172 615 1199 1177 1200
arab4 %<>%
mutate(cntry = sjmisc::to_label(country)) %>%
mutate(region = sjmisc::to_label(a1)) %>%
mutate(governorate = sjmisc::to_label(q1)) %>%
mutate(year = 2016)#%>%
# mutate(district = sjmisc::to_label(q2))
# Dependent Variable
arab4 %<>%
mutate(islamistparties = ifelse(q5182 > 5, NA, 5 - q5182)) %>%
mutate(islamistgov = ifelse(q5184 > 5, NA, 5 - q5184)) %>%
mutate(religinterfere = ifelse(q6061 > 5, NA, q6061)) %>%
mutate(religleaders = ifelse(q6062 > 5, NA, 5 - q6062)) %>%
mutate(religleadersinfl = ifelse(q6063 > 5, NA, 5 - q6063)) %>%
mutate(seperation = ifelse(q6064 > 5, NA, q6064)) %>%
mutate(religparty = Recode(q605a, "1 = 1;
2 = 1;
3 = 0;
4 = 0;
5 = 0;
98 = 0;
99 = NA")) %>%
mutate(religparty2 = Recode(q605a, "1 = 5;
2 = 4;
3 = 2;
4 = 1;
5 = 3;
98 = NA;
99 = NA"))
arab4 %<>%
mutate(female = ifelse(q1002 == 2, 1, 0)) %>%
mutate(work = ifelse(q1004 == 0 | q1004 > 5, NA, abs(q1004 - 2))) %>%
mutate(income = ifelse4cat_rec(q1016)) %>%
mutate(age = ifelse(q1001 == 0 | q1001 == 9999, NA, q1001)) %>%
mutate(educ = case_when(
q1003 == 0 ~ NA_real_,
q1003 == 98 ~ NA_real_,
q1003 == 99 ~ NA_real_,
q1003 == 5 ~ 4,
q1003 == 6 ~ 5,
q1003 == 7 ~ 6,
t1003 == 0 ~ NA_real_,
t1003 == 98 ~ NA_real_,
t1003 == 99 ~ NA_real_,
t1003 == 3 ~ 3,
t1003 == 4 ~ 4,
t1003 == 5 ~ 5,
t1003 == 6 ~ 6,
TRUE ~ as.numeric(q1003))
) %>%
mutate(globalism = ifelse(q701b == 0 | q701b > 5, NA, q701b)) %>%
mutate(pray = ifelse(q6101 == 0 | q6101 > 5, NA, 6 - q6101)) %>%
mutate(quran = ifelse(q6106 == 0 | q6106 > 5, NA, 6 - q6106)) %>%
mutate(womanwork = ifelse(q6012 == 0 | q6012 > 5, NA, q6012)) %>%
mutate(womenleader = ifelse4cat_rec(q6013)) %>%
mutate(womeneduc = ifelse4cat_rec(q6014)) %>%
mutate(nodemoc = ifelse(q6071 == 0 | q6071 > 5, NA, q6071)) %>%
mutate(genderapartuni = ifelse4cat_rec(q6074)) %>%
mutate(coverup = ifelse4cat_rec(q6076)) %>%
select(cntry, year, region, governorate , islamistparties , islamistgov, religinterfere, religleaders, religleadersinfl, seperation, religparty, religparty2, female, work, income, age, educ, globalism, pray, quran, womanwork, womenleader, womeneduc, nodemoc, genderapartuni, coverup)
Factor Analysis
f31 <- arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl) %>%
fa(1, rotate = "promax",
fm = "pa",
scores = "regression")
fa.diagram(f31)

f31
Factor Analysis using method = pa
Call: fa(r = ., nfactors = 1, rotate = "promax", scores = "regression",
fm = "pa")
Standardized loadings (pattern matrix) based upon correlation matrix
PA1 h2 u2 com
islamistparties 0.55 0.30 0.70 1
islamistgov 0.54 0.29 0.71 1
religleaders 0.71 0.50 0.50 1
religleadersinfl 0.63 0.40 0.60 1
PA1
SS loadings 1.50
Proportion Var 0.38
Mean item complexity = 1
Test of the hypothesis that 1 factor is sufficient.
The degrees of freedom for the null model are 6 and the objective function was 0.75 with Chi Square of 16491.97
The degrees of freedom for the model are 2 and the objective function was 0.09
The root mean square of the residuals (RMSR) is 0.08
The df corrected root mean square of the residuals is 0.14
The harmonic number of observations is 19654 with the empirical chi square 1517.15 with prob < 0
The total number of observations was 21915 with Likelihood Chi Square = 1941.79 with prob < 0
Tucker Lewis Index of factoring reliability = 0.647
RMSEA index = 0.21 and the 90 % confidence intervals are 0.203 0.218
BIC = 1921.8
Fit based upon off diagonal values = 0.96
Measures of factor score adequacy
PA1
Correlation of (regression) scores with factors 0.85
Multiple R square of scores with factors 0.72
Minimum correlation of possible factor scores 0.43
arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl) %>%
alpha()
Reliability analysis
Call: alpha(x = .)
raw_alpha std.alpha G6(smc) average_r S/N ase mean
0.7 0.7 0.66 0.37 2.3 0.0034 2
sd
0.71
lower alpha upper 95% confidence boundaries
0.69 0.7 0.71
Reliability if an item is dropped:
raw_alpha std.alpha G6(smc) average_r S/N
islamistparties 0.65 0.65 0.58 0.39 1.9
islamistgov 0.65 0.66 0.58 0.39 1.9
religleaders 0.60 0.60 0.51 0.33 1.5
religleadersinfl 0.64 0.64 0.54 0.37 1.7
alpha se
islamistparties 0.0042
islamistgov 0.0041
religleaders 0.0046
religleadersinfl 0.0042
Item statistics
n raw.r std.r r.cor r.drop mean sd
islamistparties 20198 0.72 0.71 0.55 0.46 1.7 0.95
islamistgov 20135 0.73 0.71 0.54 0.46 1.7 1.02
religleaders 20431 0.75 0.76 0.66 0.53 2.3 0.92
religleadersinfl 20524 0.72 0.73 0.60 0.48 2.2 0.89
Non missing response frequency for each item
1 2 3 4 5 miss
islamistparties 0.59 0.19 0.15 0.07 0 0.08
islamistgov 0.59 0.17 0.14 0.10 0 0.08
religleaders 0.21 0.38 0.31 0.10 0 0.07
religleadersinfl 0.24 0.42 0.26 0.08 0 0.06
arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl) %>%
KMO()
Kaiser-Meyer-Olkin factor adequacy
Call: KMO(r = .)
Overall MSA = 0.68
MSA for each item =
islamistparties islamistgov religleaders
0.71 0.72 0.66
religleadersinfl
0.66
arab4 %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl,
religparty2, seperation,
religinterfere) %>%
na.omit() %>%
cor()
islamistparties islamistgov religleaders
islamistparties 1.0000000 0.3760955 0.3274069
islamistgov 0.3760955 1.0000000 0.3180997
religleaders 0.3274069 0.3180997 1.0000000
religleadersinfl 0.2595854 0.3059820 0.5628358
religparty2 0.2625742 0.2409189 0.3812004
seperation 0.1409401 0.2186956 0.3190967
religinterfere 0.1393481 0.1283822 0.2070613
religleadersinfl religparty2 seperation
islamistparties 0.2595854 0.2625742 0.1409401
islamistgov 0.3059820 0.2409189 0.2186956
religleaders 0.5628358 0.3812004 0.3190967
religleadersinfl 1.0000000 0.3120300 0.2944263
religparty2 0.3120300 1.0000000 0.2819491
seperation 0.2944263 0.2819491 1.0000000
religinterfere 0.2539891 0.1671423 0.2725233
religinterfere
islamistparties 0.1393481
islamistgov 0.1283822
religleaders 0.2070613
religleadersinfl 0.2539891
religparty2 0.1671423
seperation 0.2725233
religinterfere 1.0000000
arab <- predict(f31, arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl)) %>%
data.frame() %>%
cbind(arab) %>%
mutate(islamism = PA1) #%>%
# ggplot(aes(islamism)) +
# geom_histogram() +
# facet_wrap(~cntry, scales = "free")
#sjPlot::view_df(arab, show.frq = T, show.prc = T)
Regression
vif.mer(model2)
female work
1.313155 1.270084
income age
1.062632 1.074094
educ globalism
1.155690 1.052950
personalpiety patriarchalvalues
1.076342 1.162692
liberalislam personalpiety:liberalislam
1.109287 1.026315
model1 <- arab %>%
lme4::lmer(islamism ~ female + work + income + age + educ + globalism + pray + quran + womanwork + womenleader + womeneduc + nodemoc + genderapartuni + coverup + (1|cntry/year), data = .)
texreg::screenreg(model1)
plot_model(model1, sort.est = T, show.values = T, show.p = T, value.offset = 0.5)
plot_model(model1, terms = c("nodemoc", "female"), type = "pred")
model2 <- arab %>%
lme4::lmer(islamism ~ female + work + income + age + educ + globalism + pray + quran + womanwork + womenleader + womeneduc + nodemoc + genderapartuni + coverup + nodemoc*quran + (1|cntry/year), data = .)
texreg::screenreg(model2)
view_df2 <- function (x, weight.by = NULL, altr.row.col = TRUE, show.id = TRUE,
show.type = FALSE, show.values = TRUE, show.string.values = FALSE,
show.labels = TRUE, show.frq = FALSE, show.prc = FALSE,
show.wtd.frq = FALSE, show.wtd.prc = FALSE, show.na = FALSE,
max.len = 15, sort.by.name = FALSE, wrap.labels = 50, hide.progress = FALSE,
CSS = NULL, encoding = NULL, file = NULL, use.viewer = TRUE,
no.output = FALSE, remove.spaces = TRUE)
{
get.encoding <- function(encoding, data = NULL) {
if (is.null(encoding)) {
if (!is.null(data) && is.data.frame(data)) {
# get variable label
labs <- sjlabelled::get_label(data[[1]])
# check if vectors of data frame have
# any valid label. else, default to utf-8
if (!is.null(labs) && is.character(labs))
encoding <- Encoding(sjlabelled::get_label(data[[1]]))
else
encoding <- "UTF-8"
# unknown encoding? default to utf-8
if (encoding == "unknown") encoding <- "UTF-8"
} else if (.Platform$OS.type == "unix")
encoding <- "UTF-8"
else
encoding <- "Windows-1252"
}
return(encoding)
}
has_value_labels <- function(x) {
!(is.null(attr(x, "labels", exact = T)) && is.null(attr(x, "value.labels", exact = T)))
}
sju.rmspc <- function(html.table) {
cleaned <- gsub(" <", "<", html.table, fixed = TRUE, useBytes = TRUE)
cleaned <- gsub(" <", "<", cleaned, fixed = TRUE, useBytes = TRUE)
cleaned <- gsub(" <", "<", cleaned, fixed = TRUE, useBytes = TRUE)
return(cleaned)
}
frq.value <- function(index, x, df.val, weights = NULL) {
valstring <- ""
# check if we have a valid index
if (index <= ncol(x) && !is.null(df.val[[index]])) {
# do we have weights?
if (!is.null(weights))
variab <- sjstats::weight(x[[index]], weights)
else
variab <- x[[index]]
# create frequency table. same function as for
# sjt.frq and sjp.frq
ftab <- create.frq.df(variab, 20)$mydat$frq
# remove last value, which is N for NA
if (length(ftab) == 1 && is.na(ftab)) {
valstring <- "<NA>"
} else {
for (i in 1:(length(ftab) - 1)) {
valstring <- paste0(valstring, ftab[i])
if (i < length(ftab)) valstring <- paste0(valstring, "<br>")
}
}
} else {
valstring <- ""
}
return(valstring)
}
prc.value <- function(index, x, df.val, weights = NULL) {
valstring <- ""
# check for valid indices
if (index <= ncol(x) && !is.null(df.val[[index]])) {
# do we have weights?
if (!is.null(weights))
variab <- sjstats::weight(x[[index]], weights)
else
variab <- x[[index]]
# create frequency table, but only get valid percentages
ftab <- create.frq.df(variab, 20)$mydat$valid.prc
# remove last value, which is a NA dummy
if (length(ftab) == 1 && is.na(ftab)) {
valstring <- "<NA>"
} else {
for (i in 1:(length(ftab) - 1)) {
valstring <- paste0(valstring, sprintf("%.2f", ftab[i]))
if (i < length(ftab)) valstring <- paste0(valstring, "<br>")
}
}
} else {
valstring <- ""
}
return(valstring)
}
encoding <- get.encoding(encoding, x)
if (!is.data.frame(x))
stop("Parameter needs to be a data frame!", call. = FALSE)
df.var <- sjlabelled::get_label(x)
df.val <- sjlabelled::get_labels(x)
colcnt <- ncol(x)
id <- seq_len(colcnt)
if (sort.by.name)
id <- id[order(colnames(x))]
tag.table <- "table"
tag.thead <- "thead"
tag.tdata <- "tdata"
tag.arc <- "arc"
tag.caption <- "caption"
tag.omit <- "omit"
css.table <- "border-collapse:collapse; border:none;"
css.thead <- "border-bottom:double; font-style:italic; font-weight:normal; padding:0.2cm; text-align:left; vertical-align:top;"
css.tdata <- "padding:0.2cm; text-align:left; vertical-align:top;"
css.arc <- "background-color:#eeeeee"
css.caption <- "font-weight: bold; text-align:left;"
css.omit <- "color:#999999;"
if (!is.null(CSS)) {
if (!is.null(CSS[["css.table"]]))
css.table <- ifelse(substring(CSS[["css.table"]],
1, 1) == "+", paste0(css.table, substring(CSS[["css.table"]],
2)), CSS[["css.table"]])
if (!is.null(CSS[["css.thead"]]))
css.thead <- ifelse(substring(CSS[["css.thead"]],
1, 1) == "+", paste0(css.thead, substring(CSS[["css.thead"]],
2)), CSS[["css.thead"]])
if (!is.null(CSS[["css.tdata"]]))
css.tdata <- ifelse(substring(CSS[["css.tdata"]],
1, 1) == "+", paste0(css.tdata, substring(CSS[["css.tdata"]],
2)), CSS[["css.tdata"]])
if (!is.null(CSS[["css.arc"]]))
css.arc <- ifelse(substring(CSS[["css.arc"]], 1,
1) == "+", paste0(css.arc, substring(CSS[["css.arc"]],
2)), CSS[["css.arc"]])
if (!is.null(CSS[["css.caption"]]))
css.caption <- ifelse(substring(CSS[["css.caption"]],
1, 1) == "+", paste0(css.caption, substring(CSS[["css.caption"]],
2)), CSS[["css.caption"]])
if (!is.null(CSS[["css.omit"]]))
css.omit <- ifelse(substring(CSS[["css.omit"]],
1, 1) == "+", paste0(css.omit, substring(CSS[["css.omit"]],
2)), CSS[["css.omit"]])
}
page.style <- sprintf("<style>\nhtml, body { background-color: white; }\n%s { %s }\n.%s { %s }\n.%s { %s }\n.%s { %s }\n%s { %s }\n.%s { %s }\n</style>",
tag.table, css.table, tag.thead, css.thead, tag.tdata,
css.tdata, tag.arc, css.arc, tag.caption, css.caption,
tag.omit, css.omit)
toWrite <- sprintf("<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n%s\n</head>\n<body>\n",
encoding, page.style)
page.content <- sprintf("<table>\n <caption>Data frame: %s</caption>\n",
deparse(substitute(x)))
page.content <- paste0(page.content, " <tr>\n ")
if (show.id)
page.content <- paste0(page.content, "<th class=\"thead\">ID</th>")
page.content <- paste0(page.content, "<th class=\"thead\">Name</th>")
if (show.type)
page.content <- paste0(page.content, "<th class=\"thead\">Type</th>")
page.content <- paste0(page.content, "<th class=\"thead\">Label</th>")
if (show.na)
page.content <- paste0(page.content, "<th class=\"thead\">missings</th>")
if (show.values)
page.content <- paste0(page.content, "<th class=\"thead\">Values</th>")
if (show.labels)
page.content <- paste0(page.content, "<th class=\"thead\">Value Labels</th>")
if (show.frq)
page.content <- paste0(page.content, "<th class=\"thead\">Freq.</th>")
if (show.prc)
page.content <- paste0(page.content, "<th class=\"thead\">%</th>")
if (show.wtd.frq)
page.content <- paste0(page.content, "<th class=\"thead\">weighted Freq.</th>")
if (show.wtd.prc)
page.content <- paste0(page.content, "<th class=\"thead\">weighted %</th>")
page.content <- paste0(page.content, "\n </tr>\n")
if (!hide.progress)
pb <- utils::txtProgressBar(min = 0, max = colcnt, style = 3)
for (ccnt in seq_len(colcnt)) {
index <- id[ccnt]
arcstring <- ""
if (altr.row.col)
arcstring <- ifelse(sjmisc::is_even(ccnt), " arc",
"")
page.content <- paste0(page.content, " <tr>\n")
if (show.id)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%i</td>\n",
arcstring, index))
if (!is.list(x[[index]]) && !is.null(sjlabelled::get_note(x[[index]])))
td.title.tag <- sprintf(" title=\"%s\"", sjlabelled::get_note(x[[index]]))
else td.title.tag <- ""
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\"%s>%s</td>\n",
arcstring, td.title.tag, colnames(x)[index]))
if (show.type) {
vartype <- sjmisc::var_type(x[[index]])
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, vartype))
}
if (index <= length(df.var)) {
varlab <- df.var[index]
if (!is.null(wrap.labels)) {
varlab <- sjmisc::word_wrap(varlab, wrap.labels,
"<br>")
}
}
else {
varlab <- "<NA>"
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, varlab))
if (show.na) {
if (is.list(x[[index]])) {
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\"><span class=\"omit\"><list></span></td>\n",
arcstring))
}
else {
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%i (%.2f%%)</td>\n",
arcstring, sum(is.na(x[[index]]), na.rm = T),
100 * sum(is.na(x[[index]]), na.rm = T)/nrow(x)))
}
}
if (is.numeric(x[[index]]) && !has_value_labels(x[[index]])) {
if (show.values || show.labels) {
valstring <- paste0(sprintf("%a", range(x[[index]],
na.rm = T)), collapse = "-")
if (show.values && show.labels) {
colsp <- " colspan=\"2\""
valstring <- paste0("<em>range: ", valstring,
"</em>")
}
else {
colsp <- ""
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\"%s>%s</td>\n",
arcstring, colsp, valstring))
}
}
else {
if (show.values) {
valstring <- ""
if (index <= ncol(x)) {
if (is.list(x[[index]])) {
valstring <- "<span class=\"omit\"><list></span>"
}
else {
vals <- sjlabelled::get_values(x[[index]])
if (!is.null(vals)) {
loop <- na.omit(seq_len(length(vals))[1:max.len])
for (i in loop) {
valstring <- paste0(valstring, vals[i])
if (i < length(vals))
valstring <- paste0(valstring, "<br>")
}
if (max.len < length(vals))
valstring <- paste0(valstring, "<span class=\"omit\"><...></span>")
}
}
}
else {
valstring <- "<NA>"
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.labels) {
valstring <- ""
if (index <= length(df.val)) {
if (is.list(x[[index]])) {
valstring <- "<span class=\"omit\"><list></span>"
}
else {
vals <- df.val[[index]]
if (!is.null(vals))
vals <- na.omit(vals)
if (is.character(x[[index]]) && !is.null(vals) &&
!sjmisc::is_empty(vals)) {
if (show.string.values)
vals <- sort(vals)
else vals <- "<span class=\"omit\" title =\"'show.string.values = TRUE' to show values.\"><output omitted></span>"
}
if (!is.null(vals)) {
loop <- na.omit(seq_len(length(vals))[1:max.len])
for (i in loop) {
valstring <- paste0(valstring, vals[i])
if (i < length(vals))
valstring <- paste0(valstring, "<br>")
}
if (max.len < length(vals))
valstring <- paste0(valstring, "<span class=\"omit\"><... truncated></span>")
}
}
}
else {
valstring <- "<NA>"
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
}
if (show.frq) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- frq.value(index, x, df.val)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.prc) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- prc.value(index, x, df.val)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.wtd.frq && !is.null(weight.by)) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- frq.value(index, x, df.val, weight.by)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.prc && !is.null(weight.by)) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- prc.value(index, x, df.val, weight.by)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (!hide.progress)
utils::setTxtProgressBar(pb, ccnt)
page.content <- paste0(page.content, " </tr>\n")
}
if (!hide.progress)
close(pb)
page.content <- paste(page.content, "</table>", sep = "\n")
toWrite <- paste0(toWrite, sprintf("%s\n</body></html>",
page.content))
knitr <- page.content
knitr <- gsub("class=", "style=", knitr, fixed = TRUE, useBytes = TRUE)
knitr <- gsub("<table", sprintf("<table style=\"%s\"", css.table),
knitr, fixed = TRUE, useBytes = TRUE)
knitr <- gsub(tag.tdata, css.tdata, knitr, fixed = TRUE,
useBytes = TRUE)
knitr <- gsub(tag.thead, css.thead, knitr, fixed = TRUE,
useBytes = TRUE)
knitr <- gsub(tag.arc, css.arc, knitr, fixed = TRUE, useBytes = TRUE)
if (remove.spaces) {
knitr <- sju.rmspc(knitr)
toWrite <- sju.rmspc(toWrite)
page.content <- sju.rmspc(page.content)
}
structure(class = c("sjTable", "view_df"), list(page.style = page.style,
page.content = page.content, output.complete = toWrite,
header = NULL, knitr = knitr, file = file, show = !no.output,
use.viewer = use.viewer))
}
view_df2(arab4, hide.progress = T)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyfQ0KI3BhY21hbjo6cF9pbnN0YWxsX2doKCJzeXN0YXRzL2Jpbm9jdWxhUiIpDQpwYWNtYW46OnBfbG9hZCh0aWR5dmVyc2UsIGhhdmVuLCBtYWdyaXR0ciwgY2FyLCBwc3ljaCwgc2pQbG90LCBzanN0YXRzLCBzam1pc2MsIGxtZTQsIGJpbm9jdWxhUikNCmBgYA0KDQojIExvYWQgaW4gRGF0YQ0KDQpgYGB7cn0NCmFyYWI0IDwtIHJlYWRfc3BzcygiZGF0YS9hcmFiNC5zYXYiKQ0KYXJhYjMgPC0gcmVhZF9zcHNzKCJkYXRhL2FyYWIzLnNhdiIpDQoNCiMgYXJhYjQgPC0gZ2V0KGxvYWQodXJsKCJodHRwczovL2dpdGh1Yi5jb20vZmF2c3RhdHMvR29kbHlHb3Zlcm5hbmNlL3Jhdy9tYXN0ZXIvZGF0YS9hcmFiNC5SZGF0YSIpKSkNCg0KYGBgDQoNCiMgSW5zcGVjdCBEYXRhDQoNCmBgYHtyfQ0KI2Jfc2VsZWN0IDwtIGJpbm9jdWxhUjo6Ymlub2N1bGFSKGFyYWI0KQ0KI2RwdXQoYl9zZWxlY3QkdmFyX2NvZGVzKQ0KDQojaW5kZXggPC0gYygiY291bnRyeSIsInd0IiAsInNhbXBsZSIgLCJhMSIsICJxMSIsICJxMiIsICJxMTMiLCAicTUxODIiLCANCiMicTUxODQiLCAicTYwMTMiLCAicTYwMTQiLCAicTYwMTgiLCAicTYwMTE4IiwgInE2MDVhIiwgInE2MDYxIiwgInE2MDYyIiwgDQojInE2MDYzIiwgInE2MDY0IiwgInE2MDcxIiwgInE2MDc0IiwgInE2MDc2IiwgInE3MDciLCAicTcwOCIsIA0KIyJxNzExNCIsICJxMTAwMSIsICJxMTAwMiIsICJxMTAwMyIsICJ0MTAwMyIsICJxMTAwNCIsICJxMTAwNSIsIA0KIyJxNjA5IiwgInE2MTAxIiwgInE2MTA2IiwgInExMDEyIiwgInExMDEyYSIsICJxMTAxNiIpDQojDQojYXJhYjQgJTw+JQ0KIyAgc2VsZWN0KGluZGV4KQ0KIw0KI2FyYWI0DQojdmlld19kZjIoYXJhYjMsIGhpZGUucHJvZ3Jlc3MgPSBUKQ0KIyBzYXZlKGFyYWI0LCBmaWxlID0gImRhdGEvYXJhYjQuUmRhdGEiKQ0KYGBgDQoNCiMgRmlsdGVyIERhdGENCg0KYGBge3J9DQphcmFiNCAlPD4lDQogIGZpbHRlcihxMTAxMiA9PSAxKSAlPiUjb25seSBNdXNsaW1zDQogIG11dGF0ZShzYW1wbGUgPSBpZmVsc2UoaXMubmEoc2FtcGxlKSB8IHNhbXBsZSA9PSAxLCAxLCAyKSkgJT4lIA0KICBmaWx0ZXIoc2FtcGxlICE9IDIpICNvbmx5IG5vbi1yZWZ1Z2Vlcw0KDQphcmFiMyAlPD4lDQogIGZpbHRlcihxMTAxMiA9PSAxKSAjb25seSBNdXNsaW1zDQoNCmFyYWIzDQphcmFiNA0KYGBgDQoNCiMgUmVjb2RlIERhdGENCg0KIyMgQXJhYjMNCg0KYGBge3J9DQoNCmFyYWIzICU8PiUgDQogIG11dGF0ZShjbnRyeSA9IHNqbWlzYzo6dG9fbGFiZWwoY291bnRyeSkpICU+JSANCiAgbXV0YXRlKHJlZ2lvbiA9IHNqbWlzYzo6dG9fbGFiZWwoYTEpKSAlPiUgDQogIG11dGF0ZShnb3Zlcm5vcmF0ZSA9IHNqbWlzYzo6dG9fbGFiZWwocTEpKSAlPiUgDQogIG11dGF0ZSh5ZWFyID0gbHVicmlkYXRlOjp5ZWFyKGRhdGUpKQ0KDQogICMgRGVwZW5kZW50IFZhcmlhYmxlDQphcmFiMyAlPD4lIA0KICBtdXRhdGUoaXNsYW1pc3RwYXJ0aWVzMSA9IGlmZWxzZShxNTE4YTIgPiA1LCBOQSwgNSAtIHE1MThhMikpICU+JQ0KICBtdXRhdGUoaXNsYW1pc3RwYXJ0aWVzMiA9IGlmZWxzZShxNTE4YjIgPiA1LCBOQSwgNSAtIHE1MThiMikpICU+JSANCiAgbXV0YXRlKGlzbGFtaXN0cGFydGllcyA9IGNhc2Vfd2hlbigNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMSA9PSAxIH4gMSwNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMSA9PSAyIH4gMiwNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMSA9PSAzIH4gMywNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMSA9PSA0IH4gNCwNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMiA9PSAxIH4gMSwNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMiA9PSAyIH4gMiwNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMiA9PSAzIH4gMywNCiAgICAgICAgaXNsYW1pc3RwYXJ0aWVzMiA9PSA0IH4gNCkNCiAgICApICU+JSAgDQogIG11dGF0ZShpc2xhbWlzdGdvdiA9IGlmZWxzZShxNTE4NCA+IDUsIE5BLCA1IC0gcTUxODQpKSAlPiUgDQogIG11dGF0ZShyZWxpZ2ludGVyZmVyZSA9IGlmZWxzZShxNjA2MSA+IDUsIE5BLCBxNjA2MSkpICU+JSANCiAgbXV0YXRlKHJlbGlnbGVhZGVycyA9IGlmZWxzZShxNjA2MiA+IDUsIE5BLCA1IC0gcTYwNjIpKSAlPiUgDQogIG11dGF0ZShyZWxpZ2xlYWRlcnNpbmZsID0gaWZlbHNlKHE2MDYzID4gNSwgTkEsIDUgLSBxNjA2MykpICU+JQ0KICBtdXRhdGUoc2VwZXJhdGlvbiA9IGlmZWxzZShxNjA2NCA+IDUsIE5BLCBxNjA2NCkpICU+JSANCiAgbXV0YXRlKHJlbGlncGFydHkgPSBSZWNvZGUocTYwNWEsICIxID0gMTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyID0gMTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAzID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA1ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDggPSAwOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOSA9IE5BIikpICU+JSANCiAgbXV0YXRlKHJlbGlncGFydHkyID0gUmVjb2RlKHE2MDVhLCAiMSA9IDU7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgPSA0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAzID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDUgPSAzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDggPSBOQTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5ID0gTkEiKSkNCg0KaWZlbHNlNGNhdF9yZWMgPC0gZnVuY3Rpb24odmFyaWFibGUpIHsNCiAgcmVjb2RlZCA8LSBpZmVsc2UodmFyaWFibGUgPT0gMCB8IHZhcmlhYmxlID4gNSwgTkEsIDUgLSB2YXJpYWJsZSkNCiAgcmV0dXJuKHJlY29kZWQpDQp9DQoNCg0KYXJhYjMgJTw+JSANCiAgbXV0YXRlKGZlbWFsZSA9IGlmZWxzZShzZXggPT0gMiwgMSwgMCkpICU+JSANCiAgbXV0YXRlKHdvcmsgPSBpZmVsc2UocTEwMDQgPT0gMCB8IHExMDA0ID4gNSwgTkEsIGFicyhxMTAwNCAtIDIpKSkgJT4lIA0KICBtdXRhdGUoaW5jb21lID0gaWZlbHNlNGNhdF9yZWMocTEwMTYpKSAlPiUgDQogIG11dGF0ZShhZ2UgPSBpZmVsc2UocTEwMDEgPT0gMCB8IHExMDAxID09IDk5OTksIE5BLCBxMTAwMSkpICU+JSANCiAgbXV0YXRlKGVkdWMgPSBjYXNlX3doZW4oDQogICAgICAgIHExMDAzID09IDAgfiBOQV9yZWFsXywNCiAgICAgICAgcTEwMDMgPT0gOTkgfiBOQV9yZWFsXywNCiAgICAgICAgcTEwMDMgPT0gNSB+IDQsDQogICAgICAgIHExMDAzID09IDYgfiA1LA0KICAgICAgICBxMTAwMyA9PSA3IH4gNiwNCiAgICAgICAgcTEwMDN5ZW0gPT0gMCB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwM3llbSA9PSA5OSB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwM3llbSA9PSA0IH4gMywNCiAgICAgICAgcTEwMDN5ZW0gPT0gNSB+IDQsDQogICAgICAgIHExMDAzeWVtID09IDYgfiA1LA0KICAgICAgICBxMTAwM3llbSA9PSA3IH4gNSwNCiAgICAgICAgcTEwMDN5ZW0gPT0gOCB+IDYsDQogICAgICAgIHExMDAzdCA9PSAwIH4gTkFfcmVhbF8sDQogICAgICAgIHExMDAzdCA9PSA5OSB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwM3QgPT0gMSB+IDEsDQogICAgICAgIHExMDAzdCA9PSAyIH4gMiwNCiAgICAgICAgcTEwMDN0ID09IDMgfiAzLA0KICAgICAgICBxMTAwM3QgPT0gNCB+IDQsDQogICAgICAgIHExMDAzdCA9PSA1IH4gNSwNCiAgICAgICAgcTEwMDN0ID09IDYgfiA2LA0KICAgIFRSVUUgfiBhcy5udW1lcmljKHExMDAzKSkNCiAgICApICU+JSANCiAgbXV0YXRlKGdsb2JhbGlzbSA9IGlmZWxzZShxNzAxYiA9PSAwIHwgcTcwMWIgPiA1LCBOQSwgcTcwMWIpKSAlPiUgDQogIG11dGF0ZShwcmF5ID0gaWZlbHNlKHE2MTAxID09IDAgfCBxNjEwMSA+IDUsIE5BLCA2IC0gcTYxMDEpKSAlPiUgDQogIG11dGF0ZShxdXJhbiA9IGlmZWxzZShxNjEwNiA9PSAwIHwgcTYxMDYgPiA1LCBOQSwgNiAtIHE2MTA2KSkgJT4lDQogIG11dGF0ZSh3b21hbndvcmsgPSBpZmVsc2UocTYwMTIgPT0gMCB8IHE2MDEyID4gNSwgTkEsIHE2MDEyKSkgJT4lIA0KICBtdXRhdGUod29tZW5sZWFkZXIgPSBpZmVsc2U0Y2F0X3JlYyhxNjAxMykpICU+JSANCiAgbXV0YXRlKHdvbWVuZWR1YyA9IGlmZWxzZTRjYXRfcmVjKHE2MDE0KSkgJT4lIA0KICBtdXRhdGUobm9kZW1vYyA9IGlmZWxzZShxNjA3MSA9PSAwIHwgcTYwNzEgPiA1LCBOQSwgcTYwNzEpKSAlPiUgDQogIG11dGF0ZShnZW5kZXJhcGFydHVuaSA9IGlmZWxzZTRjYXRfcmVjKHE2MDc0KSkgJT4lIA0KICBtdXRhdGUoY292ZXJ1cCA9IGlmZWxzZTRjYXRfcmVjKHE2MDc2KSkgJT4lIA0KICBzZWxlY3QoY250cnksIHllYXIsIHJlZ2lvbiwgZ292ZXJub3JhdGUsIGlzbGFtaXN0cGFydGllcyAsIGlzbGFtaXN0Z292LCByZWxpZ2ludGVyZmVyZSwgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsLCBzZXBlcmF0aW9uLCByZWxpZ3BhcnR5LCByZWxpZ3BhcnR5MiwgZmVtYWxlLCB3b3JrLCBpbmNvbWUsICBhZ2UsIGVkdWMsIGdsb2JhbGlzbSwgcHJheSwgcXVyYW4sIHdvbWFud29yaywgd29tZW5sZWFkZXIsIHdvbWVuZWR1Yywgbm9kZW1vYywgZ2VuZGVyYXBhcnR1bmksIGNvdmVydXApDQoNCg0KDQoNCg0KYGBgDQoNCiMjIEFyYWI0DQoNCmBgYHtyfQ0KdGFibGUoYXJhYjQkY291bnRyeSkNCg0KYXJhYjQgJTw+JSANCiAgbXV0YXRlKGNudHJ5ID0gc2ptaXNjOjp0b19sYWJlbChjb3VudHJ5KSkgJT4lIA0KICBtdXRhdGUocmVnaW9uID0gc2ptaXNjOjp0b19sYWJlbChhMSkpICU+JSANCiAgbXV0YXRlKGdvdmVybm9yYXRlID0gc2ptaXNjOjp0b19sYWJlbChxMSkpICU+JSANCiAgbXV0YXRlKHllYXIgPSAyMDE2KSMlPiUNCiMgIG11dGF0ZShkaXN0cmljdCA9IHNqbWlzYzo6dG9fbGFiZWwocTIpKSANCg0KIyBEZXBlbmRlbnQgVmFyaWFibGUNCmFyYWI0ICU8PiUgDQogIG11dGF0ZShpc2xhbWlzdHBhcnRpZXMgPSBpZmVsc2UocTUxODIgPiA1LCBOQSwgNSAtIHE1MTgyKSkgJT4lIA0KICBtdXRhdGUoaXNsYW1pc3Rnb3YgPSBpZmVsc2UocTUxODQgPiA1LCBOQSwgNSAtIHE1MTg0KSkgJT4lIA0KICBtdXRhdGUocmVsaWdpbnRlcmZlcmUgPSBpZmVsc2UocTYwNjEgPiA1LCBOQSwgcTYwNjEpKSAlPiUgDQogIG11dGF0ZShyZWxpZ2xlYWRlcnMgPSBpZmVsc2UocTYwNjIgPiA1LCBOQSwgNSAtIHE2MDYyKSkgJT4lIA0KICBtdXRhdGUocmVsaWdsZWFkZXJzaW5mbCA9IGlmZWxzZShxNjA2MyA+IDUsIE5BLCA1IC0gcTYwNjMpKSAlPiUNCiAgbXV0YXRlKHNlcGVyYXRpb24gPSBpZmVsc2UocTYwNjQgPiA1LCBOQSwgcTYwNjQpKSAlPiUgDQogIG11dGF0ZShyZWxpZ3BhcnR5ID0gUmVjb2RlKHE2MDVhLCAiMSA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMyA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNSA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5OCA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5OSA9IE5BIikpICU+JSANCiAgbXV0YXRlKHJlbGlncGFydHkyID0gUmVjb2RlKHE2MDVhLCAiMSA9IDU7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgPSA0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAzID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDUgPSAzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDk4ID0gTkE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOTkgPSBOQSIpKQ0KDQoNCg0KYXJhYjQgJTw+JSANCiAgbXV0YXRlKGZlbWFsZSA9IGlmZWxzZShxMTAwMiA9PSAyLCAxLCAwKSkgJT4lIA0KICBtdXRhdGUod29yayA9IGlmZWxzZShxMTAwNCA9PSAwIHwgcTEwMDQgPiA1LCBOQSwgYWJzKHExMDA0IC0gMikpKSAlPiUgDQogIG11dGF0ZShpbmNvbWUgPSBpZmVsc2U0Y2F0X3JlYyhxMTAxNikpICU+JSANCiAgbXV0YXRlKGFnZSA9IGlmZWxzZShxMTAwMSA9PSAwIHwgcTEwMDEgPT0gOTk5OSwgTkEsIHExMDAxKSkgJT4lIA0KICBtdXRhdGUoZWR1YyA9IGNhc2Vfd2hlbigNCiAgICAgICAgcTEwMDMgPT0gMCB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwMyA9PSA5OCB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwMyA9PSA5OSB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwMyA9PSA1IH4gNCwNCiAgICAgICAgcTEwMDMgPT0gNiB+IDUsDQogICAgICAgIHExMDAzID09IDcgfiA2LA0KICAgICAgICB0MTAwMyA9PSAwIH4gTkFfcmVhbF8sDQogICAgICAgIHQxMDAzID09IDk4IH4gTkFfcmVhbF8sDQogICAgICAgIHQxMDAzID09IDk5IH4gTkFfcmVhbF8sDQogICAgICAgIHQxMDAzID09IDMgfiAzLA0KICAgICAgICB0MTAwMyA9PSA0IH4gNCwNCiAgICAgICAgdDEwMDMgPT0gNSB+IDUsDQogICAgICAgIHQxMDAzID09IDYgfiA2LA0KICAgIFRSVUUgfiBhcy5udW1lcmljKHExMDAzKSkNCiAgICApICU+JSANCiAgbXV0YXRlKGdsb2JhbGlzbSA9IGlmZWxzZShxNzAxYiA9PSAwIHwgcTcwMWIgPiA1LCBOQSwgcTcwMWIpKSAlPiUgDQogIG11dGF0ZShwcmF5ID0gaWZlbHNlKHE2MTAxID09IDAgfCBxNjEwMSA+IDUsIE5BLCA2IC0gcTYxMDEpKSAlPiUgDQogIG11dGF0ZShxdXJhbiA9IGlmZWxzZShxNjEwNiA9PSAwIHwgcTYxMDYgPiA1LCBOQSwgNiAtIHE2MTA2KSkgJT4lIA0KICBtdXRhdGUod29tYW53b3JrID0gaWZlbHNlKHE2MDEyID09IDAgfCBxNjAxMiA+IDUsIE5BLCBxNjAxMikpICU+JSANCiAgbXV0YXRlKHdvbWVubGVhZGVyID0gaWZlbHNlNGNhdF9yZWMocTYwMTMpKSAlPiUgDQogIG11dGF0ZSh3b21lbmVkdWMgPSBpZmVsc2U0Y2F0X3JlYyhxNjAxNCkpICU+JSANCiAgbXV0YXRlKG5vZGVtb2MgPSBpZmVsc2UocTYwNzEgPT0gMCB8IHE2MDcxID4gNSwgTkEsIHE2MDcxKSkgJT4lIA0KICBtdXRhdGUoZ2VuZGVyYXBhcnR1bmkgPSBpZmVsc2U0Y2F0X3JlYyhxNjA3NCkpICU+JSANCiAgbXV0YXRlKGNvdmVydXAgPSBpZmVsc2U0Y2F0X3JlYyhxNjA3NikpICU+JSANCiAgc2VsZWN0KGNudHJ5LCB5ZWFyLCByZWdpb24sIGdvdmVybm9yYXRlICwgaXNsYW1pc3RwYXJ0aWVzICwgaXNsYW1pc3Rnb3YsIHJlbGlnaW50ZXJmZXJlLCByZWxpZ2xlYWRlcnMsIHJlbGlnbGVhZGVyc2luZmwsIHNlcGVyYXRpb24sIHJlbGlncGFydHksIHJlbGlncGFydHkyLCBmZW1hbGUsIHdvcmssIGluY29tZSwgIGFnZSwgZWR1YywgZ2xvYmFsaXNtLCBwcmF5LCBxdXJhbiwgd29tYW53b3JrLCB3b21lbmxlYWRlciwgd29tZW5lZHVjLCBub2RlbW9jLCBnZW5kZXJhcGFydHVuaSwgY292ZXJ1cCkNCg0KYGBgDQoNCg0KIyBNZXJnaW5nDQoNCmBgYHtyfQ0KYXJhYjM7YXJhYjQNCg0KYXJhYiA8LSByYmluZChhcmFiNCxhcmFiMykNCg0KYXJhYg0KDQp0YWJsZShhcmFiJHllYXIpDQp0YWJsZShhcmFiJGNudHJ5KQ0KYGBgDQoNCiMgRmFjdG9yIEFuYWx5c2lzDQoNCmBgYHtyfQ0KZjMxIDwtIGFyYWIgJT4lIA0KICBzZWxlY3QoaXNsYW1pc3RwYXJ0aWVzLCBpc2xhbWlzdGdvdiwgDQogICAgICAgICByZWxpZ2xlYWRlcnMsIHJlbGlnbGVhZGVyc2luZmwpICU+JSANCiAgZmEoMSwgcm90YXRlID0gInByb21heCIsICAgDQogICAgICAgIGZtID0gInBhIiwNCiAgICAgICAgc2NvcmVzID0gInJlZ3Jlc3Npb24iKSAgICAgICAgICAgDQpmYS5kaWFncmFtKGYzMSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpmMzEgICAgICAgICAgICAgIA0KDQphcmFiICU+JSANCiAgc2VsZWN0KGlzbGFtaXN0cGFydGllcywgaXNsYW1pc3Rnb3YsIA0KICAgICAgICAgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsKSAlPiUgDQogIGFscGhhKCkgDQoNCmFyYWIgJT4lIA0KICBzZWxlY3QoaXNsYW1pc3RwYXJ0aWVzLCBpc2xhbWlzdGdvdiwgDQogICAgICAgICByZWxpZ2xlYWRlcnMsIHJlbGlnbGVhZGVyc2luZmwpICU+JSANCiAgS01PKCkgDQoNCg0KYXJhYjQgJT4lIA0KICBzZWxlY3QoaXNsYW1pc3RwYXJ0aWVzLCBpc2xhbWlzdGdvdiwgDQogICAgICAgICByZWxpZ2xlYWRlcnMsIHJlbGlnbGVhZGVyc2luZmwsDQogICAgICAgICByZWxpZ3BhcnR5Miwgc2VwZXJhdGlvbiwNCiAgICAgICAgIHJlbGlnaW50ZXJmZXJlKSAlPiUgDQogIG5hLm9taXQoKSAlPiUgDQogIGNvcigpICANCg0KYXJhYiA8LSBwcmVkaWN0KGYzMSwgYXJhYiAlPiUgDQogIHNlbGVjdChpc2xhbWlzdHBhcnRpZXMsIGlzbGFtaXN0Z292LCANCiAgICAgICAgIHJlbGlnbGVhZGVycywgcmVsaWdsZWFkZXJzaW5mbCkpICU+JSANCiAgZGF0YS5mcmFtZSgpICU+JSANCiAgY2JpbmQoYXJhYikgJT4lIA0KICBtdXRhdGUoaXNsYW1pc20gPSBQQTEpICMlPiUgDQojICBnZ3Bsb3QoYWVzKGlzbGFtaXNtKSkgKw0KIyAgZ2VvbV9oaXN0b2dyYW0oKSArDQojICBmYWNldF93cmFwKH5jbnRyeSwgc2NhbGVzID0gImZyZWUiKQ0KDQojc2pQbG90Ojp2aWV3X2RmKGFyYWIsIHNob3cuZnJxID0gVCwgc2hvdy5wcmMgPSBUKQ0KDQpgYGANCg0KIyBDcmVhdGluZyBpbmRpY2VzDQoNCmBgYHtyfQ0KZjEgPC0gYXJhYiAlPiUgDQogIHNlbGVjdCh3b21hbndvcmssIHdvbWVubGVhZGVyLCB3b21lbmVkdWMpICU+JSANCiAgZmEoMSwgcm90YXRlID0gInByb21heCIsICAgDQogICAgICAgIGZtID0gInBhIiwNCiAgICAgICAgc2NvcmVzID0gInJlZ3Jlc3Npb24iKSAgICAgICAgICAgDQpmYS5kaWFncmFtKGYxKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCmYxICAgICAgICANCg0KZjIgPC0gYXJhYiAlPiUgDQogIHNlbGVjdChwcmF5LCBxdXJhbikgJT4lIA0KICBmYSgxLCByb3RhdGUgPSAicHJvbWF4IiwgICANCiAgICAgICAgZm0gPSAicGEiLA0KICAgICAgICBzY29yZXMgPSAicmVncmVzc2lvbiIpICAgICAgICAgICANCmZhLmRpYWdyYW0oZjIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KZjIgICAgDQoNCmYzIDwtIGFyYWIgJT4lIA0KICBzZWxlY3Qobm9kZW1vYywgZ2VuZGVyYXBhcnR1bmksIGNvdmVydXApICU+JSANCiAgZmEoMSwgcm90YXRlID0gInByb21heCIsICAgDQogICAgICAgIGZtID0gInBhIiwNCiAgICAgICAgc2NvcmVzID0gInJlZ3Jlc3Npb24iKSAgICAgICAgICAgDQpmYS5kaWFncmFtKGYzKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCmYzICAgIA0KDQphcmFiICU+JSANCiAgc2VsZWN0KG5vZGVtb2MsIGdlbmRlcmFwYXJ0dW5pLCBjb3ZlcnVwKSAlPiUgDQogIEtNTygpDQoNCnJhbmdlMDEgPC0gZnVuY3Rpb24oeCl7KHggLSBtaW4oeCwgbmEucm0gPSBUKSkgLyAobWF4KHgsIG5hLnJtID0gVCkgLSBtaW4oeCwgbmEucm0gPSBUKSl9DQoNCg0KYXJhYiAlPD4lIA0KICBtdXRhdGUocGF0cmlhcmNoYWx2YWx1ZXMgPSB3b21hbndvcmsgKyB3b21lbmxlYWRlciArIHdvbWVuZWR1YykgICU+JSANCiAgbXV0YXRlKHBlcnNvbmFscGlldHkgPSBwcmF5ICsgcXVyYW4pICU+JSANCiMgIG11dGF0ZShpc2xhbWlzbSA9IGlzbGFtaXNtKSAlPiUgDQogIG11dGF0ZShsaWJlcmFsaXNsYW0gPSBub2RlbW9jICsgZ2VuZGVyYXBhcnR1bmkgKyBjb3ZlcnVwKSAlPiUgDQogIG11dGF0ZV9pZigucHJlZGljYXRlID0gaXMuZG91YmxlLCBzY2FsZSkgDQoNCg0KYGBgDQoNCg0KIyBSZWdyZXNzaW9uDQoNCmBgYHtyfQ0KbW9kZWwwIDwtIGFyYWIgJT4lIA0KICBsbWU0OjpsbWVyKGlzbGFtaXNtIH4gMSArICgxfGNudHJ5L3llYXIpLCBkYXRhID0gLikNCg0KaWNjKG1vZGVsMCkNCg0KbW9kZWwxIDwtIGFyYWIgJT4lIA0KICBsbWU0OjpsbWVyKGlzbGFtaXNtIH4gZmVtYWxlICsgd29yayArIGluY29tZSArIGFnZSArIGVkdWMgKyBnbG9iYWxpc20gKyBwZXJzb25hbHBpZXR5ICsgcGF0cmlhcmNoYWx2YWx1ZXMgKyBsaWJlcmFsaXNsYW0gKyAoMXxjbnRyeS95ZWFyKSwgZGF0YSA9IC4pDQoNCnRleHJlZzo6c2NyZWVucmVnKG1vZGVsMSkNCg0KcGxvdF9tb2RlbChtb2RlbDEsIHR5cGUgPSAicmUiLCBzb3J0LmVzdCA9IFQsIHNob3cudmFsdWVzID0gVCwgc2hvdy5wID0gVCwgdmFsdWUub2Zmc2V0ID0gMC41KQ0KDQpwbG90X21vZGVsKG1vZGVsMSwgc29ydC5lc3QgPSBULCBzaG93LnZhbHVlcyA9IFQsIHNob3cucCA9IFQsIHZhbHVlLm9mZnNldCA9IDAuNSkNCg0KcGxvdF9tb2RlbChtb2RlbDEsIHRlcm1zID0gYygibGliZXJhbGlzbGFtIiwgInBlcnNvbmFscGlldHkiKSwgdHlwZSA9ICJwcmVkIikNCg0KaWNjKG1vZGVsMSkNCg0KbW9kZWwyIDwtIGFyYWIgJT4lIA0KICBsbWU0OjpsbWVyKGlzbGFtaXNtIH4gZmVtYWxlICsgd29yayArIGluY29tZSArIGFnZSArIGVkdWMgKyBnbG9iYWxpc20gKyBwZXJzb25hbHBpZXR5ICsgcGF0cmlhcmNoYWx2YWx1ZXMgKyBsaWJlcmFsaXNsYW0gKyBsaWJlcmFsaXNsYW0qcGVyc29uYWxwaWV0eSArICgxfGNudHJ5L3llYXIpLCBkYXRhID0gLikNCg0KdGV4cmVnOjpzY3JlZW5yZWcobW9kZWwyKQ0KDQoNCnBsb3RfbW9kZWwobW9kZWwyLCBzb3J0LmVzdCA9IFQsIHNob3cudmFsdWVzID0gVCwgc2hvdy5wID0gVCwgdmFsdWUub2Zmc2V0ID0gMC41KQ0KDQoNCnBsb3RfbW9kZWwobW9kZWwyLCB0eXBlID0gImludCIpDQoNCnZpZi5tZXIgPC0gZnVuY3Rpb24gKGZpdCkgew0KICAjIyBhZGFwdGVkIGZyb20gcm1zOjp2aWYNCiAgDQogIHYgPC0gdmNvdihmaXQpDQogIG5hbSA8LSBuYW1lcyhmaXhlZihmaXQpKQ0KICANCiAgIyMgZXhjbHVkZSBpbnRlcmNlcHRzDQogIG5zIDwtIHN1bSgxICogKG5hbSA9PSAiSW50ZXJjZXB0IiB8IG5hbSA9PSAiKEludGVyY2VwdCkiKSkNCiAgaWYgKG5zID4gMCkgew0KICAgIHYgPC0gdlstKDE6bnMpLCAtKDE6bnMpLCBkcm9wID0gRkFMU0VdDQogICAgbmFtIDwtIG5hbVstKDE6bnMpXQ0KICB9DQogIA0KICBkIDwtIGRpYWcodileMC41DQogIHYgPC0gZGlhZyhzb2x2ZSh2LyhkICVvJSBkKSkpDQogIG5hbWVzKHYpIDwtIG5hbQ0KICB2DQp9DQoNCnZpZi5tZXIobW9kZWwyKQ0KDQpgYGANCg0KDQpgYGB7cn0NCm1vZGVsMSA8LSBhcmFiICU+JSANCiAgbG1lNDo6bG1lcihpc2xhbWlzbSB+IGZlbWFsZSArIHdvcmsgKyBpbmNvbWUgKyBhZ2UgKyBlZHVjICsgZ2xvYmFsaXNtICsgcHJheSArIHF1cmFuICsgd29tYW53b3JrICsgd29tZW5sZWFkZXIgKyB3b21lbmVkdWMgKyBub2RlbW9jICsgZ2VuZGVyYXBhcnR1bmkgKyBjb3ZlcnVwICsgKDF8Y250cnkveWVhciksIGRhdGEgPSAuKQ0KDQp0ZXhyZWc6OnNjcmVlbnJlZyhtb2RlbDEpDQoNCnBsb3RfbW9kZWwobW9kZWwxLCBzb3J0LmVzdCA9IFQsIHNob3cudmFsdWVzID0gVCwgc2hvdy5wID0gVCwgdmFsdWUub2Zmc2V0ID0gMC41KQ0KDQoNCnBsb3RfbW9kZWwobW9kZWwxLCB0ZXJtcyA9IGMoIm5vZGVtb2MiLCAiZmVtYWxlIiksIHR5cGUgPSAicHJlZCIpDQoNCm1vZGVsMiA8LSBhcmFiICU+JSANCiAgbG1lNDo6bG1lcihpc2xhbWlzbSB+IGZlbWFsZSArIHdvcmsgKyBpbmNvbWUgKyBhZ2UgKyBlZHVjICsgZ2xvYmFsaXNtICsgcHJheSArIHF1cmFuICsgd29tYW53b3JrICsgd29tZW5sZWFkZXIgKyB3b21lbmVkdWMgKyBub2RlbW9jICsgZ2VuZGVyYXBhcnR1bmkgKyBjb3ZlcnVwICsgbm9kZW1vYypxdXJhbiArICgxfGNudHJ5L3llYXIpLCBkYXRhID0gLikNCg0KdGV4cmVnOjpzY3JlZW5yZWcobW9kZWwyKQ0KYGBgDQoNCg0KYGBge3J9DQp2aWV3X2RmMiA8LSBmdW5jdGlvbiAoeCwgd2VpZ2h0LmJ5ID0gTlVMTCwgYWx0ci5yb3cuY29sID0gVFJVRSwgc2hvdy5pZCA9IFRSVUUsIA0KICBzaG93LnR5cGUgPSBGQUxTRSwgc2hvdy52YWx1ZXMgPSBUUlVFLCBzaG93LnN0cmluZy52YWx1ZXMgPSBGQUxTRSwgDQogIHNob3cubGFiZWxzID0gVFJVRSwgc2hvdy5mcnEgPSBGQUxTRSwgc2hvdy5wcmMgPSBGQUxTRSwgDQogIHNob3cud3RkLmZycSA9IEZBTFNFLCBzaG93Lnd0ZC5wcmMgPSBGQUxTRSwgc2hvdy5uYSA9IEZBTFNFLCANCiAgbWF4LmxlbiA9IDE1LCBzb3J0LmJ5Lm5hbWUgPSBGQUxTRSwgd3JhcC5sYWJlbHMgPSA1MCwgaGlkZS5wcm9ncmVzcyA9IEZBTFNFLCANCiAgQ1NTID0gTlVMTCwgZW5jb2RpbmcgPSBOVUxMLCBmaWxlID0gTlVMTCwgdXNlLnZpZXdlciA9IFRSVUUsIA0KICBuby5vdXRwdXQgPSBGQUxTRSwgcmVtb3ZlLnNwYWNlcyA9IFRSVUUpIA0Kew0KICBnZXQuZW5jb2RpbmcgPC0gZnVuY3Rpb24oZW5jb2RpbmcsIGRhdGEgPSBOVUxMKSB7DQogIGlmIChpcy5udWxsKGVuY29kaW5nKSkgew0KICAgIGlmICghaXMubnVsbChkYXRhKSAmJiBpcy5kYXRhLmZyYW1lKGRhdGEpKSB7DQogICAgICAjIGdldCB2YXJpYWJsZSBsYWJlbA0KICAgICAgbGFicyA8LSBzamxhYmVsbGVkOjpnZXRfbGFiZWwoZGF0YVtbMV1dKQ0KICAgICAgIyBjaGVjayBpZiB2ZWN0b3JzIG9mIGRhdGEgZnJhbWUgaGF2ZQ0KICAgICAgIyBhbnkgdmFsaWQgbGFiZWwuIGVsc2UsIGRlZmF1bHQgdG8gdXRmLTgNCiAgICAgIGlmICghaXMubnVsbChsYWJzKSAmJiBpcy5jaGFyYWN0ZXIobGFicykpDQogICAgICAgIGVuY29kaW5nIDwtIEVuY29kaW5nKHNqbGFiZWxsZWQ6OmdldF9sYWJlbChkYXRhW1sxXV0pKQ0KICAgICAgZWxzZQ0KICAgICAgICBlbmNvZGluZyA8LSAiVVRGLTgiDQogICAgICAjIHVua25vd24gZW5jb2Rpbmc/IGRlZmF1bHQgdG8gdXRmLTgNCiAgICAgIGlmIChlbmNvZGluZyA9PSAidW5rbm93biIpIGVuY29kaW5nIDwtICJVVEYtOCINCiAgICB9IGVsc2UgaWYgKC5QbGF0Zm9ybSRPUy50eXBlID09ICJ1bml4IikNCiAgICAgIGVuY29kaW5nIDwtICJVVEYtOCINCiAgICBlbHNlDQogICAgICBlbmNvZGluZyA8LSAiV2luZG93cy0xMjUyIg0KICB9DQogIHJldHVybihlbmNvZGluZykNCn0NCg0KICBoYXNfdmFsdWVfbGFiZWxzIDwtIGZ1bmN0aW9uKHgpIHsNCiAgIShpcy5udWxsKGF0dHIoeCwgImxhYmVscyIsIGV4YWN0ID0gVCkpICYmIGlzLm51bGwoYXR0cih4LCAidmFsdWUubGFiZWxzIiwgZXhhY3QgPSBUKSkpDQp9DQoNCiAgc2p1LnJtc3BjIDwtIGZ1bmN0aW9uKGh0bWwudGFibGUpIHsNCiAgY2xlYW5lZCA8LSBnc3ViKCIgICAgICA8IiwgIjwiLCBodG1sLnRhYmxlLCBmaXhlZCA9IFRSVUUsIHVzZUJ5dGVzID0gVFJVRSkNCiAgY2xlYW5lZCA8LSBnc3ViKCIgICAgPCIsICI8IiwgY2xlYW5lZCwgZml4ZWQgPSBUUlVFLCB1c2VCeXRlcyA9IFRSVUUpDQogIGNsZWFuZWQgPC0gZ3N1YigiICA8IiwgIjwiLCBjbGVhbmVkLCBmaXhlZCA9IFRSVUUsIHVzZUJ5dGVzID0gVFJVRSkNCiAgcmV0dXJuKGNsZWFuZWQpDQogIH0NCiAgDQogIGZycS52YWx1ZSA8LSBmdW5jdGlvbihpbmRleCwgeCwgZGYudmFsLCB3ZWlnaHRzID0gTlVMTCkgew0KICB2YWxzdHJpbmcgPC0gIiINCiAgIyBjaGVjayBpZiB3ZSBoYXZlIGEgdmFsaWQgaW5kZXgNCiAgaWYgKGluZGV4IDw9IG5jb2woeCkgJiYgIWlzLm51bGwoZGYudmFsW1tpbmRleF1dKSkgew0KICAgICMgZG8gd2UgaGF2ZSB3ZWlnaHRzPw0KICAgIGlmICghaXMubnVsbCh3ZWlnaHRzKSkNCiAgICAgIHZhcmlhYiA8LSBzanN0YXRzOjp3ZWlnaHQoeFtbaW5kZXhdXSwgd2VpZ2h0cykNCiAgICBlbHNlDQogICAgICB2YXJpYWIgPC0geFtbaW5kZXhdXQ0KICAgICMgY3JlYXRlIGZyZXF1ZW5jeSB0YWJsZS4gc2FtZSBmdW5jdGlvbiBhcyBmb3INCiAgICAjIHNqdC5mcnEgYW5kIHNqcC5mcnENCiAgICBmdGFiIDwtIGNyZWF0ZS5mcnEuZGYodmFyaWFiLCAyMCkkbXlkYXQkZnJxDQogICAgIyByZW1vdmUgbGFzdCB2YWx1ZSwgd2hpY2ggaXMgTiBmb3IgTkENCiAgICBpZiAobGVuZ3RoKGZ0YWIpID09IDEgJiYgaXMubmEoZnRhYikpIHsNCiAgICAgIHZhbHN0cmluZyA8LSAiPE5BPiINCiAgICB9IGVsc2Ugew0KICAgICAgZm9yIChpIGluIDE6KGxlbmd0aChmdGFiKSAtIDEpKSB7DQogICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCBmdGFiW2ldKQ0KICAgICAgICBpZiAoaSA8IGxlbmd0aChmdGFiKSkgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsICI8YnI+IikNCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSB7DQogICAgdmFsc3RyaW5nIDwtICIiDQogIH0NCiAgcmV0dXJuKHZhbHN0cmluZykNCn0NCg0KcHJjLnZhbHVlIDwtIGZ1bmN0aW9uKGluZGV4LCB4LCBkZi52YWwsIHdlaWdodHMgPSBOVUxMKSB7DQogIHZhbHN0cmluZyA8LSAiIg0KICAjIGNoZWNrIGZvciB2YWxpZCBpbmRpY2VzDQogIGlmIChpbmRleCA8PSBuY29sKHgpICYmICFpcy5udWxsKGRmLnZhbFtbaW5kZXhdXSkpIHsNCiAgICAjIGRvIHdlIGhhdmUgd2VpZ2h0cz8NCiAgICBpZiAoIWlzLm51bGwod2VpZ2h0cykpDQogICAgICB2YXJpYWIgPC0gc2pzdGF0czo6d2VpZ2h0KHhbW2luZGV4XV0sIHdlaWdodHMpDQogICAgZWxzZQ0KICAgICAgdmFyaWFiIDwtIHhbW2luZGV4XV0NCiAgICAjIGNyZWF0ZSBmcmVxdWVuY3kgdGFibGUsIGJ1dCBvbmx5IGdldCB2YWxpZCBwZXJjZW50YWdlcw0KICAgIGZ0YWIgPC0gY3JlYXRlLmZycS5kZih2YXJpYWIsIDIwKSRteWRhdCR2YWxpZC5wcmMNCiAgICAjIHJlbW92ZSBsYXN0IHZhbHVlLCB3aGljaCBpcyBhIE5BIGR1bW15DQogICAgaWYgKGxlbmd0aChmdGFiKSA9PSAxICYmIGlzLm5hKGZ0YWIpKSB7DQogICAgICB2YWxzdHJpbmcgPC0gIjxOQT4iDQogICAgfSBlbHNlIHsNCiAgICAgIGZvciAoaSBpbiAxOihsZW5ndGgoZnRhYikgLSAxKSkgew0KICAgICAgICB2YWxzdHJpbmcgPC0gcGFzdGUwKHZhbHN0cmluZywgc3ByaW50ZigiJS4yZiIsIGZ0YWJbaV0pKQ0KICAgICAgICBpZiAoaSA8IGxlbmd0aChmdGFiKSkgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsICI8YnI+IikNCiAgICAgIH0NCiAgICB9DQogIH0gZWxzZSB7DQogICAgdmFsc3RyaW5nIDwtICIiDQogIH0NCiAgcmV0dXJuKHZhbHN0cmluZykNCn0NCiAgDQogIGVuY29kaW5nIDwtIGdldC5lbmNvZGluZyhlbmNvZGluZywgeCkNCiAgaWYgKCFpcy5kYXRhLmZyYW1lKHgpKSANCiAgICBzdG9wKCJQYXJhbWV0ZXIgbmVlZHMgdG8gYmUgYSBkYXRhIGZyYW1lISIsIGNhbGwuID0gRkFMU0UpDQogIGRmLnZhciA8LSBzamxhYmVsbGVkOjpnZXRfbGFiZWwoeCkNCiAgZGYudmFsIDwtIHNqbGFiZWxsZWQ6OmdldF9sYWJlbHMoeCkNCiAgY29sY250IDwtIG5jb2woeCkNCiAgaWQgPC0gc2VxX2xlbihjb2xjbnQpDQogIGlmIChzb3J0LmJ5Lm5hbWUpIA0KICAgIGlkIDwtIGlkW29yZGVyKGNvbG5hbWVzKHgpKV0NCiAgdGFnLnRhYmxlIDwtICJ0YWJsZSINCiAgdGFnLnRoZWFkIDwtICJ0aGVhZCINCiAgdGFnLnRkYXRhIDwtICJ0ZGF0YSINCiAgdGFnLmFyYyA8LSAiYXJjIg0KICB0YWcuY2FwdGlvbiA8LSAiY2FwdGlvbiINCiAgdGFnLm9taXQgPC0gIm9taXQiDQogIGNzcy50YWJsZSA8LSAiYm9yZGVyLWNvbGxhcHNlOmNvbGxhcHNlOyBib3JkZXI6bm9uZTsiDQogIGNzcy50aGVhZCA8LSAiYm9yZGVyLWJvdHRvbTpkb3VibGU7IGZvbnQtc3R5bGU6aXRhbGljOyBmb250LXdlaWdodDpub3JtYWw7IHBhZGRpbmc6MC4yY207IHRleHQtYWxpZ246bGVmdDsgdmVydGljYWwtYWxpZ246dG9wOyINCiAgY3NzLnRkYXRhIDwtICJwYWRkaW5nOjAuMmNtOyB0ZXh0LWFsaWduOmxlZnQ7IHZlcnRpY2FsLWFsaWduOnRvcDsiDQogIGNzcy5hcmMgPC0gImJhY2tncm91bmQtY29sb3I6I2VlZWVlZSINCiAgY3NzLmNhcHRpb24gPC0gImZvbnQtd2VpZ2h0OiBib2xkOyB0ZXh0LWFsaWduOmxlZnQ7Ig0KICBjc3Mub21pdCA8LSAiY29sb3I6Izk5OTk5OTsiDQogIGlmICghaXMubnVsbChDU1MpKSB7DQogICAgaWYgKCFpcy5udWxsKENTU1tbImNzcy50YWJsZSJdXSkpIA0KICAgICAgY3NzLnRhYmxlIDwtIGlmZWxzZShzdWJzdHJpbmcoQ1NTW1siY3NzLnRhYmxlIl1dLCANCiAgICAgICAgMSwgMSkgPT0gIisiLCBwYXN0ZTAoY3NzLnRhYmxlLCBzdWJzdHJpbmcoQ1NTW1siY3NzLnRhYmxlIl1dLCANCiAgICAgICAgMikpLCBDU1NbWyJjc3MudGFibGUiXV0pDQogICAgaWYgKCFpcy5udWxsKENTU1tbImNzcy50aGVhZCJdXSkpIA0KICAgICAgY3NzLnRoZWFkIDwtIGlmZWxzZShzdWJzdHJpbmcoQ1NTW1siY3NzLnRoZWFkIl1dLCANCiAgICAgICAgMSwgMSkgPT0gIisiLCBwYXN0ZTAoY3NzLnRoZWFkLCBzdWJzdHJpbmcoQ1NTW1siY3NzLnRoZWFkIl1dLCANCiAgICAgICAgMikpLCBDU1NbWyJjc3MudGhlYWQiXV0pDQogICAgaWYgKCFpcy5udWxsKENTU1tbImNzcy50ZGF0YSJdXSkpIA0KICAgICAgY3NzLnRkYXRhIDwtIGlmZWxzZShzdWJzdHJpbmcoQ1NTW1siY3NzLnRkYXRhIl1dLCANCiAgICAgICAgMSwgMSkgPT0gIisiLCBwYXN0ZTAoY3NzLnRkYXRhLCBzdWJzdHJpbmcoQ1NTW1siY3NzLnRkYXRhIl1dLCANCiAgICAgICAgMikpLCBDU1NbWyJjc3MudGRhdGEiXV0pDQogICAgaWYgKCFpcy5udWxsKENTU1tbImNzcy5hcmMiXV0pKSANCiAgICAgIGNzcy5hcmMgPC0gaWZlbHNlKHN1YnN0cmluZyhDU1NbWyJjc3MuYXJjIl1dLCAxLCANCiAgICAgICAgMSkgPT0gIisiLCBwYXN0ZTAoY3NzLmFyYywgc3Vic3RyaW5nKENTU1tbImNzcy5hcmMiXV0sIA0KICAgICAgICAyKSksIENTU1tbImNzcy5hcmMiXV0pDQogICAgaWYgKCFpcy5udWxsKENTU1tbImNzcy5jYXB0aW9uIl1dKSkgDQogICAgICBjc3MuY2FwdGlvbiA8LSBpZmVsc2Uoc3Vic3RyaW5nKENTU1tbImNzcy5jYXB0aW9uIl1dLCANCiAgICAgICAgMSwgMSkgPT0gIisiLCBwYXN0ZTAoY3NzLmNhcHRpb24sIHN1YnN0cmluZyhDU1NbWyJjc3MuY2FwdGlvbiJdXSwgDQogICAgICAgIDIpKSwgQ1NTW1siY3NzLmNhcHRpb24iXV0pDQogICAgaWYgKCFpcy5udWxsKENTU1tbImNzcy5vbWl0Il1dKSkgDQogICAgICBjc3Mub21pdCA8LSBpZmVsc2Uoc3Vic3RyaW5nKENTU1tbImNzcy5vbWl0Il1dLCANCiAgICAgICAgMSwgMSkgPT0gIisiLCBwYXN0ZTAoY3NzLm9taXQsIHN1YnN0cmluZyhDU1NbWyJjc3Mub21pdCJdXSwgDQogICAgICAgIDIpKSwgQ1NTW1siY3NzLm9taXQiXV0pDQogIH0NCiAgcGFnZS5zdHlsZSA8LSBzcHJpbnRmKCI8c3R5bGU+XG5odG1sLCBib2R5IHsgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IH1cbiVzIHsgJXMgfVxuLiVzIHsgJXMgfVxuLiVzIHsgJXMgfVxuLiVzIHsgJXMgfVxuJXMgeyAlcyB9XG4uJXMgeyAlcyB9XG48L3N0eWxlPiIsIA0KICAgIHRhZy50YWJsZSwgY3NzLnRhYmxlLCB0YWcudGhlYWQsIGNzcy50aGVhZCwgdGFnLnRkYXRhLCANCiAgICBjc3MudGRhdGEsIHRhZy5hcmMsIGNzcy5hcmMsIHRhZy5jYXB0aW9uLCBjc3MuY2FwdGlvbiwgDQogICAgdGFnLm9taXQsIGNzcy5vbWl0KQ0KICB0b1dyaXRlIDwtIHNwcmludGYoIjxodG1sPlxuPGhlYWQ+XG48bWV0YSBodHRwLWVxdWl2PVwiQ29udGVudC10eXBlXCIgY29udGVudD1cInRleHQvaHRtbDtjaGFyc2V0PSVzXCI+XG4lc1xuPC9oZWFkPlxuPGJvZHk+XG4iLCANCiAgICBlbmNvZGluZywgcGFnZS5zdHlsZSkNCiAgcGFnZS5jb250ZW50IDwtIHNwcmludGYoIjx0YWJsZT5cbiAgPGNhcHRpb24+RGF0YSBmcmFtZTogJXM8L2NhcHRpb24+XG4iLCANCiAgICBkZXBhcnNlKHN1YnN0aXR1dGUoeCkpKQ0KICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIiAgPHRyPlxuICAgICIpDQogIGlmIChzaG93LmlkKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+SUQ8L3RoPiIpDQogIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiPHRoIGNsYXNzPVwidGhlYWRcIj5OYW1lPC90aD4iKQ0KICBpZiAoc2hvdy50eXBlKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+VHlwZTwvdGg+IikNCiAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPkxhYmVsPC90aD4iKQ0KICBpZiAoc2hvdy5uYSkgDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPm1pc3NpbmdzPC90aD4iKQ0KICBpZiAoc2hvdy52YWx1ZXMpIA0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiPHRoIGNsYXNzPVwidGhlYWRcIj5WYWx1ZXM8L3RoPiIpDQogIGlmIChzaG93LmxhYmVscykgDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPlZhbHVlIExhYmVsczwvdGg+IikNCiAgaWYgKHNob3cuZnJxKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+RnJlcS48L3RoPiIpDQogIGlmIChzaG93LnByYykgDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPiU8L3RoPiIpDQogIGlmIChzaG93Lnd0ZC5mcnEpIA0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiPHRoIGNsYXNzPVwidGhlYWRcIj53ZWlnaHRlZCBGcmVxLjwvdGg+IikNCiAgaWYgKHNob3cud3RkLnByYykgDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPndlaWdodGVkICU8L3RoPiIpDQogIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiXG4gIDwvdHI+XG4iKQ0KICBpZiAoIWhpZGUucHJvZ3Jlc3MpIA0KICAgIHBiIDwtIHV0aWxzOjp0eHRQcm9ncmVzc0JhcihtaW4gPSAwLCBtYXggPSBjb2xjbnQsIHN0eWxlID0gMykNCiAgZm9yIChjY250IGluIHNlcV9sZW4oY29sY250KSkgew0KICAgIGluZGV4IDwtIGlkW2NjbnRdDQogICAgYXJjc3RyaW5nIDwtICIiDQogICAgaWYgKGFsdHIucm93LmNvbCkgDQogICAgICBhcmNzdHJpbmcgPC0gaWZlbHNlKHNqbWlzYzo6aXNfZXZlbihjY250KSwgIiBhcmMiLCANCiAgICAgICAgIiIpDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICIgIDx0cj5cbiIpDQogICAgaWYgKHNob3cuaWQpIA0KICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JWk8L3RkPlxuIiwgDQogICAgICAgIGFyY3N0cmluZywgaW5kZXgpKQ0KICAgIGlmICghaXMubGlzdCh4W1tpbmRleF1dKSAmJiAhaXMubnVsbChzamxhYmVsbGVkOjpnZXRfbm90ZSh4W1tpbmRleF1dKSkpIA0KICAgICAgdGQudGl0bGUudGFnIDwtIHNwcmludGYoIiB0aXRsZT1cIiVzXCIiLCBzamxhYmVsbGVkOjpnZXRfbm90ZSh4W1tpbmRleF1dKSkNCiAgICBlbHNlIHRkLnRpdGxlLnRhZyA8LSAiIg0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiJXM+JXM8L3RkPlxuIiwgDQogICAgICBhcmNzdHJpbmcsIHRkLnRpdGxlLnRhZywgY29sbmFtZXMoeClbaW5kZXhdKSkNCiAgICBpZiAoc2hvdy50eXBlKSB7DQogICAgICB2YXJ0eXBlIDwtIHNqbWlzYzo6dmFyX3R5cGUoeFtbaW5kZXhdXSkNCiAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgICBhcmNzdHJpbmcsIHZhcnR5cGUpKQ0KICAgIH0NCiAgICBpZiAoaW5kZXggPD0gbGVuZ3RoKGRmLnZhcikpIHsNCiAgICAgIHZhcmxhYiA8LSBkZi52YXJbaW5kZXhdDQogICAgICBpZiAoIWlzLm51bGwod3JhcC5sYWJlbHMpKSB7DQogICAgICAgIHZhcmxhYiA8LSBzam1pc2M6OndvcmRfd3JhcCh2YXJsYWIsIHdyYXAubGFiZWxzLCANCiAgICAgICAgICAiPGJyPiIpDQogICAgICB9DQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgdmFybGFiIDwtICI8TkE+Ig0KICAgIH0NCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgc3ByaW50ZigiICAgIDx0ZCBjbGFzcz1cInRkYXRhJXNcIj4lczwvdGQ+XG4iLCANCiAgICAgIGFyY3N0cmluZywgdmFybGFiKSkNCiAgICBpZiAoc2hvdy5uYSkgew0KICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIHsNCiAgICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+PHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0O2xpc3QmZ3Q7PC9zcGFuPjwvdGQ+XG4iLCANCiAgICAgICAgICBhcmNzdHJpbmcpKQ0KICAgICAgfQ0KICAgICAgZWxzZSB7DQogICAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVpICglLjJmJSUpPC90ZD5cbiIsIA0KICAgICAgICAgIGFyY3N0cmluZywgc3VtKGlzLm5hKHhbW2luZGV4XV0pLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAxMDAgKiBzdW0oaXMubmEoeFtbaW5kZXhdXSksIG5hLnJtID0gVCkvbnJvdyh4KSkpDQogICAgICB9DQogICAgfQ0KICAgIGlmIChpcy5udW1lcmljKHhbW2luZGV4XV0pICYmICFoYXNfdmFsdWVfbGFiZWxzKHhbW2luZGV4XV0pKSB7DQogICAgICBpZiAoc2hvdy52YWx1ZXMgfHwgc2hvdy5sYWJlbHMpIHsNCiAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMChzcHJpbnRmKCIlYSIsIHJhbmdlKHhbW2luZGV4XV0sIA0KICAgICAgICAgIG5hLnJtID0gVCkpLCBjb2xsYXBzZSA9ICItIikNCiAgICAgICAgaWYgKHNob3cudmFsdWVzICYmIHNob3cubGFiZWxzKSB7DQogICAgICAgICAgY29sc3AgPC0gIiBjb2xzcGFuPVwiMlwiIg0KICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAoIjxlbT5yYW5nZTogIiwgdmFsc3RyaW5nLCANCiAgICAgICAgICAgICI8L2VtPiIpDQogICAgICAgIH0NCiAgICAgICAgZWxzZSB7DQogICAgICAgICAgY29sc3AgPC0gIiINCiAgICAgICAgfQ0KICAgICAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgc3ByaW50ZigiICAgIDx0ZCBjbGFzcz1cInRkYXRhJXNcIiVzPiVzPC90ZD5cbiIsIA0KICAgICAgICAgIGFyY3N0cmluZywgY29sc3AsIHZhbHN0cmluZykpDQogICAgICB9DQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgaWYgKHNob3cudmFsdWVzKSB7DQogICAgICAgIHZhbHN0cmluZyA8LSAiIg0KICAgICAgICBpZiAoaW5kZXggPD0gbmNvbCh4KSkgew0KICAgICAgICAgIGlmIChpcy5saXN0KHhbW2luZGV4XV0pKSB7DQogICAgICAgICAgICB2YWxzdHJpbmcgPC0gIjxzcGFuIGNsYXNzPVwib21pdFwiPiZsdDtsaXN0Jmd0Ozwvc3Bhbj4iDQogICAgICAgICAgfQ0KICAgICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgdmFscyA8LSBzamxhYmVsbGVkOjpnZXRfdmFsdWVzKHhbW2luZGV4XV0pDQogICAgICAgICAgICBpZiAoIWlzLm51bGwodmFscykpIHsNCiAgICAgICAgICAgICAgbG9vcCA8LSBuYS5vbWl0KHNlcV9sZW4obGVuZ3RoKHZhbHMpKVsxOm1heC5sZW5dKQ0KICAgICAgICAgICAgICBmb3IgKGkgaW4gbG9vcCkgew0KICAgICAgICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCB2YWxzW2ldKQ0KICAgICAgICAgICAgICAgIGlmIChpIDwgbGVuZ3RoKHZhbHMpKSANCiAgICAgICAgICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCAiPGJyPiIpDQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgaWYgKG1heC5sZW4gPCBsZW5ndGgodmFscykpIA0KICAgICAgICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0Oy4uLiZndDs8L3NwYW4+IikNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZWxzZSB7DQogICAgICAgICAgdmFsc3RyaW5nIDwtICI8TkE+Ig0KICAgICAgICB9DQogICAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgICAgIGFyY3N0cmluZywgdmFsc3RyaW5nKSkNCiAgICAgIH0NCiAgICAgIGlmIChzaG93LmxhYmVscykgew0KICAgICAgICB2YWxzdHJpbmcgPC0gIiINCiAgICAgICAgaWYgKGluZGV4IDw9IGxlbmd0aChkZi52YWwpKSB7DQogICAgICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIHsNCiAgICAgICAgICAgIHZhbHN0cmluZyA8LSAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0O2xpc3QmZ3Q7PC9zcGFuPiINCiAgICAgICAgICB9DQogICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICB2YWxzIDwtIGRmLnZhbFtbaW5kZXhdXQ0KICAgICAgICAgICAgaWYgKCFpcy5udWxsKHZhbHMpKSANCiAgICAgICAgICAgICAgdmFscyA8LSBuYS5vbWl0KHZhbHMpDQogICAgICAgICAgICBpZiAoaXMuY2hhcmFjdGVyKHhbW2luZGV4XV0pICYmICFpcy5udWxsKHZhbHMpICYmIA0KICAgICAgICAgICAgICAhc2ptaXNjOjppc19lbXB0eSh2YWxzKSkgew0KICAgICAgICAgICAgICBpZiAoc2hvdy5zdHJpbmcudmFsdWVzKSANCiAgICAgICAgICAgICAgICB2YWxzIDwtIHNvcnQodmFscykNCiAgICAgICAgICAgICAgZWxzZSB2YWxzIDwtICI8c3BhbiBjbGFzcz1cIm9taXRcIiB0aXRsZSA9XCInc2hvdy5zdHJpbmcudmFsdWVzID0gVFJVRScgdG8gc2hvdyB2YWx1ZXMuXCI+Jmx0O291dHB1dCBvbWl0dGVkJmd0Ozwvc3Bhbj4iDQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoIWlzLm51bGwodmFscykpIHsNCiAgICAgICAgICAgICAgbG9vcCA8LSBuYS5vbWl0KHNlcV9sZW4obGVuZ3RoKHZhbHMpKVsxOm1heC5sZW5dKQ0KICAgICAgICAgICAgICBmb3IgKGkgaW4gbG9vcCkgew0KICAgICAgICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCB2YWxzW2ldKQ0KICAgICAgICAgICAgICAgIGlmIChpIDwgbGVuZ3RoKHZhbHMpKSANCiAgICAgICAgICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCAiPGJyPiIpDQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgaWYgKG1heC5sZW4gPCBsZW5ndGgodmFscykpIA0KICAgICAgICAgICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0Oy4uLiB0cnVuY2F0ZWQmZ3Q7PC9zcGFuPiIpDQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGVsc2Ugew0KICAgICAgICAgIHZhbHN0cmluZyA8LSAiPE5BPiINCiAgICAgICAgfQ0KICAgICAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgc3ByaW50ZigiICAgIDx0ZCBjbGFzcz1cInRkYXRhJXNcIj4lczwvdGQ+XG4iLCANCiAgICAgICAgICBhcmNzdHJpbmcsIHZhbHN0cmluZykpDQogICAgICB9DQogICAgfQ0KICAgIGlmIChzaG93LmZycSkgew0KICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIA0KICAgICAgICB2YWxzdHJpbmcgPC0gIjxzcGFuIGNsYXNzPVwib21pdFwiPiZsdDtsaXN0Jmd0Ozwvc3Bhbj4iDQogICAgICBlbHNlIHZhbHN0cmluZyA8LSBmcnEudmFsdWUoaW5kZXgsIHgsIGRmLnZhbCkNCiAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgICBhcmNzdHJpbmcsIHZhbHN0cmluZykpDQogICAgfQ0KICAgIGlmIChzaG93LnByYykgew0KICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIA0KICAgICAgICB2YWxzdHJpbmcgPC0gIjxzcGFuIGNsYXNzPVwib21pdFwiPiZsdDtsaXN0Jmd0Ozwvc3Bhbj4iDQogICAgICBlbHNlIHZhbHN0cmluZyA8LSBwcmMudmFsdWUoaW5kZXgsIHgsIGRmLnZhbCkNCiAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgICBhcmNzdHJpbmcsIHZhbHN0cmluZykpDQogICAgfQ0KICAgIGlmIChzaG93Lnd0ZC5mcnEgJiYgIWlzLm51bGwod2VpZ2h0LmJ5KSkgew0KICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIA0KICAgICAgICB2YWxzdHJpbmcgPC0gIjxzcGFuIGNsYXNzPVwib21pdFwiPiZsdDtsaXN0Jmd0Ozwvc3Bhbj4iDQogICAgICBlbHNlIHZhbHN0cmluZyA8LSBmcnEudmFsdWUoaW5kZXgsIHgsIGRmLnZhbCwgd2VpZ2h0LmJ5KQ0KICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JXM8L3RkPlxuIiwgDQogICAgICAgIGFyY3N0cmluZywgdmFsc3RyaW5nKSkNCiAgICB9DQogICAgaWYgKHNob3cucHJjICYmICFpcy5udWxsKHdlaWdodC5ieSkpIHsNCiAgICAgIGlmIChpcy5saXN0KHhbW2luZGV4XV0pKSANCiAgICAgICAgdmFsc3RyaW5nIDwtICI8c3BhbiBjbGFzcz1cIm9taXRcIj4mbHQ7bGlzdCZndDs8L3NwYW4+Ig0KICAgICAgZWxzZSB2YWxzdHJpbmcgPC0gcHJjLnZhbHVlKGluZGV4LCB4LCBkZi52YWwsIHdlaWdodC5ieSkNCiAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgICBhcmNzdHJpbmcsIHZhbHN0cmluZykpDQogICAgfQ0KICAgIGlmICghaGlkZS5wcm9ncmVzcykgDQogICAgICB1dGlsczo6c2V0VHh0UHJvZ3Jlc3NCYXIocGIsIGNjbnQpDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICIgIDwvdHI+XG4iKQ0KICB9DQogIGlmICghaGlkZS5wcm9ncmVzcykgDQogICAgY2xvc2UocGIpDQogIHBhZ2UuY29udGVudCA8LSBwYXN0ZShwYWdlLmNvbnRlbnQsICI8L3RhYmxlPiIsIHNlcCA9ICJcbiIpDQogIHRvV3JpdGUgPC0gcGFzdGUwKHRvV3JpdGUsIHNwcmludGYoIiVzXG48L2JvZHk+PC9odG1sPiIsIA0KICAgIHBhZ2UuY29udGVudCkpDQogIGtuaXRyIDwtIHBhZ2UuY29udGVudA0KICBrbml0ciA8LSBnc3ViKCJjbGFzcz0iLCAic3R5bGU9Iiwga25pdHIsIGZpeGVkID0gVFJVRSwgdXNlQnl0ZXMgPSBUUlVFKQ0KICBrbml0ciA8LSBnc3ViKCI8dGFibGUiLCBzcHJpbnRmKCI8dGFibGUgc3R5bGU9XCIlc1wiIiwgY3NzLnRhYmxlKSwgDQogICAga25pdHIsIGZpeGVkID0gVFJVRSwgdXNlQnl0ZXMgPSBUUlVFKQ0KICBrbml0ciA8LSBnc3ViKHRhZy50ZGF0YSwgY3NzLnRkYXRhLCBrbml0ciwgZml4ZWQgPSBUUlVFLCANCiAgICB1c2VCeXRlcyA9IFRSVUUpDQogIGtuaXRyIDwtIGdzdWIodGFnLnRoZWFkLCBjc3MudGhlYWQsIGtuaXRyLCBmaXhlZCA9IFRSVUUsIA0KICAgIHVzZUJ5dGVzID0gVFJVRSkNCiAga25pdHIgPC0gZ3N1Yih0YWcuYXJjLCBjc3MuYXJjLCBrbml0ciwgZml4ZWQgPSBUUlVFLCB1c2VCeXRlcyA9IFRSVUUpDQogIGlmIChyZW1vdmUuc3BhY2VzKSB7DQogICAga25pdHIgPC0gc2p1LnJtc3BjKGtuaXRyKQ0KICAgIHRvV3JpdGUgPC0gc2p1LnJtc3BjKHRvV3JpdGUpDQogICAgcGFnZS5jb250ZW50IDwtIHNqdS5ybXNwYyhwYWdlLmNvbnRlbnQpDQogIH0NCiAgc3RydWN0dXJlKGNsYXNzID0gYygic2pUYWJsZSIsICJ2aWV3X2RmIiksIGxpc3QocGFnZS5zdHlsZSA9IHBhZ2Uuc3R5bGUsIA0KICAgIHBhZ2UuY29udGVudCA9IHBhZ2UuY29udGVudCwgb3V0cHV0LmNvbXBsZXRlID0gdG9Xcml0ZSwgDQogICAgaGVhZGVyID0gTlVMTCwga25pdHIgPSBrbml0ciwgZmlsZSA9IGZpbGUsIHNob3cgPSAhbm8ub3V0cHV0LCANCiAgICB1c2Uudmlld2VyID0gdXNlLnZpZXdlcikpDQp9DQoNCnZpZXdfZGYyKGFyYWI0LCBoaWRlLnByb2dyZXNzID0gVCkNCmBgYA0KDQoNCg==